/**
 * 将多个参数通过闭包转换为单个参数调用的过程，在某些参数复用场景下使用
 * @param {Function} arg1 
 * @param {Function} arg2 
 */
function curry(a, b) {
  return a + b;
}

function curryFactory(fn) {
  // 取除第一个参数外的参数列表
  let args1 = [].slice.call(arguments, 1);
  console.log(args1)
  return function() {
    let newArgs = args1.concat([].slice.call(arguments));
    return fn.apply(this, newArgs);
  }
}

var build1 = curryFactory(curry, 1, 4);
var build2 = build1(3);
console.log(build2)

// 第二版
var _ = {};

function partial(fn) {
    var args = [].slice.call(arguments, 1);
    return function() {
        var position = 0, len = args.length;   //  len = 2  args[0] = _ args[1] = 20
        for(var i = 0; i < len; i++) {
            args[i] = args[i] === _ ? arguments[position++] : args[i]
        }
        // args[0] = 5, args[1] = 20 position = 1; argument.length = 2
        console.log(args)
        while(position < arguments.length) args.push(arguments[position++]);
        // args = [5, 20, 30]
        console.log(args)
        return fn.apply(this, args);
    };
};

var subtract = function(a, b, c) { return b - a - c; };
subFrom20 = partial(subtract, _, _, 20);
console.log(subFrom20(5, 30, 40));
